﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using AForge.Imaging.Filters;
using AForge.Imaging;

namespace Clustering
{
    public class AdaptiveThreshold
    {
        private LedPatternSeparator ledPatternSeparator;
        private Bitmap background;
        private Bitmap foreground;

        private FiltersSequence filterSequence;

        private int numberOfPatterns = 2;
        private int numberOfLedsInPattern = 8;
        private int minBlobSize = 1;

        private int bestBlobSize;

        public int BestBlobSize
        {
            get { return bestBlobSize; }
        }

        public int MinBlobSize
        {
            get { return minBlobSize; }
            set { minBlobSize = value; }
        }

        public AdaptiveThreshold(LedPatternSeparator ledPatternSeparator, Bitmap background, Bitmap foreground)
        {
            this.ledPatternSeparator = ledPatternSeparator;
            this.background = background;
            this.foreground = foreground;
        }

        public FiltersSequence GenerateFilterSequence()
        {


            Difference differenceFilter = new Difference(this.background);
            GrayscaleBT709 grayscale = new GrayscaleBT709();

            ColorFiltering cf = new ColorFiltering();

            Bitmap differenceBmp = differenceFilter.Apply(this.foreground);
            Bitmap newBmp = null;

            FiltersSequence goodFilterSequence = null;
            int startRange = 255;
            Dilatation dilatation = new Dilatation(new short[,] { { 1, 1, 1 }, { 1, 1, 1 }, { 1, 1, 1 } });
            while (minBlobSize < 10 && startRange >= 0)
            {
                startRange = 245;

                Bitmap[] clusters = null;


                int cluster1Blobs = 0;
                int cluster2Blobs = 0;
                do
                {
                    cf.Green = cf.Red = cf.Blue = new AForge.IntRange(startRange, 255);


                    newBmp =
                        //dilatation.Apply(
                        cf.Apply(differenceBmp)
                        //   )
                        ;

                    clusters = this.ledPatternSeparator.FindClusters(newBmp);

                    if (clusters == null)
                    {
                        startRange -= 5;
                        continue;
                    }
                    BlobCounter bc1 = new BlobCounter(grayscale.Apply(clusters[0]));
                    BlobCounter bc2 = new BlobCounter(grayscale.Apply(clusters[1]));


                    bc1.MinWidth = this.minBlobSize;
                    bc1.MinHeight = this.minBlobSize;
                    bc2.MinWidth = this.minBlobSize;
                    bc2.MinHeight = this.minBlobSize;

                    bc1.FilterBlobs = true;
                    bc2.FilterBlobs = true;

                    bc1.ProcessImage(grayscale.Apply(clusters[0]));
                    bc2.ProcessImage(grayscale.Apply(clusters[1]));



                    //Blob[] blobs1 = bc1.GetObjectInformation();
                    //Blob[] blobs2 = bc2.GetObjectInformation();

                    Blob[] blobs1 = null;
                    Blob[] blobs2 = null;

                    cluster1Blobs = blobs1.Length;
                    cluster2Blobs = blobs2.Length;

                    startRange -= 5;

                    //Bitmap tmp1 = clusters[0];

                    //Bitmap tmp2 = clusters[1];

                    //Graphics g1 = Graphics.FromImage(tmp1);
                    //Graphics g2 = Graphics.FromImage(tmp2);
                    //for (int i = 0; i < blobs1.Length; i++)
                    //{
                    //    g1.DrawRectangle(Pens.Red, blobs1[i].Rectangle);
                    //}
                    //for (int i = 0; i < blobs2.Length; i++)
                    //{
                    //    g2.DrawRectangle(Pens.Red, blobs2[i].Rectangle);
                    //}
                    //tmp1.Save("1.bmp");
                    //tmp2.Save("2.bmp");

                } while ((cluster1Blobs < this.numberOfLedsInPattern || cluster2Blobs < this.numberOfLedsInPattern) && startRange >= 0);
                if (startRange >= 0 && cluster1Blobs >= this.numberOfLedsInPattern && cluster2Blobs >= this.numberOfLedsInPattern)
                {
                    goodFilterSequence = new FiltersSequence(differenceFilter, new ColorFiltering(
                        cf.Red, cf.Green, cf.Blue));
                    this.bestBlobSize = minBlobSize;
                }
                else
                    break;
                minBlobSize++;
            }

            return goodFilterSequence;
        }


    }
}
